package com.golxen;

import com.golxen.framework.activity.ActivityPlugin;
import com.golxen.framework.common.CommandPlugin;
import com.golxen.framework.common.ConfigPlugin;
import com.golxen.framework.common.BuiltinPlugin;
import com.golxen.framework.common.server.agent.AgentServer;
import com.golxen.framework.common.server.cross.CrossBaseServer;
import com.golxen.framework.common.server.game.GameAppPlugin;
import com.golxen.framework.common.server.game.GameServer;
import com.golxen.framework.event.condition.ConditionPlugin;
import com.golxen.framework.manager.ManagerPlugin;
import com.golxen.framework.PluginSwitch;
import com.golxen.framework.common.ShutDownPlugin;
import com.golxen.framework.common.server.cross.CrossAppPlugin;
import com.golxen.framework.log.LogPlugin;
import com.golxen.framework.module.ModulePlugin;
import com.golxen.framework.redis.RedisPlugin;
import com.golxen.framework.timers.TimerPlugin;
import com.golxen.framework.user.UserPlugin;
import com.golxen.framework.user.player.GamePlayerMgr;
import com.golxen.framework.user.player.PlayerPlugin;
import com.mysql.cj.util.LogUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import com.golxen.utils.LogUtil;

@SpringBootApplication
public class App {

    public static void main(String[] args) throws Throwable {
        SpringApplication springApplication=new SpringApplication(App.class);
        springApplication.addListeners((ApplicationEnvironmentPreparedEvent event)->{
            try {
                LogUtil.CONSOLE.info("app start");
                BuiltinPlugin.print();

                //启动开始注册插件

                //这里是跨服和游戏服同时要的插件
                PluginSwitch.registPlugin(ShutDownPlugin.class);
                PluginSwitch.registPlugin(LogPlugin.class);

                //跨服插件
                if (BuiltinPlugin.isCrossServer()) {
                    PluginSwitch.registPlugin(CrossAppPlugin.class);
                }

                //游戏服插件
                if (BuiltinPlugin.isGameServer()) {
                    PluginSwitch.registPlugin(ModulePlugin.class);  //用户功能模块管理
                    PluginSwitch.registPlugin(GameAppPlugin.class);  //游戏服通用插件（可再里面管理注册其他定时或管理类）
                    PluginSwitch.registPlugin(ConditionPlugin.class);  //任务条件事件监听
                    PluginSwitch.registPlugin(ActivityPlugin.class);  //活动
                    PluginSwitch.registPlugin(CommandPlugin.class);  //命令管理
                    PluginSwitch.registPlugin(PlayerPlugin.class);  //玩家
                    PluginSwitch.registPlugin(UserPlugin.class);  //用户（用户信息管理，区别上面的玩家实例）
                }

                //插件执行
                PluginSwitch.start();

                //注册启动时额外启动的管理类
                if (BuiltinPlugin.isGameServer()){
                    ManagerPlugin.registMgr(GamePlayerMgr.class);
                }


                //跨服先启动
                if (BuiltinPlugin.isCrossServer()) {
                    LogUtil.CONSOLE.info("======CrossServer startup begin");
                    CrossBaseServer.main();
                    LogUtil.CONSOLE.info("======CrossServer startup end");
                }

                //然后游戏服启动其次代理服
                if (BuiltinPlugin.isGameServer()) {
                    LogUtil.CONSOLE.info("======GameServer startup begin");
                    GameServer.main();
                    LogUtil.CONSOLE.info("======GameServer startup end");
                    LogUtil.CONSOLE.info("======AgentServer startup begin");
                    AgentServer.main();
                    LogUtil.CONSOLE.info("======AgentServer startup end");
                }


                //执行注册的管理类初始化方法（包括前面插件里注册的），因为有些是独立额外启动的管理类，所以不用插件注册器执行管理类插件
                //启动游戏服和跨服时还有单独启动其他插件，所以管理类插件得放后面这里
                ManagerPlugin.start();

                //所有准备好后启动定时器插件
                TimerPlugin.start();


            } catch (Throwable t) {
                LogUtil.CONSOLE.error("", t);
                System.exit(1);
            }
        });

        springApplication.setRegisterShutdownHook(false);

        //配置相关的插件可以在这里先启动
        ConfigPlugin.start();
        BuiltinPlugin.start();

        //跨服不使用嵌入式web服务器，代理服务器要建立websocket，要先用http请求升级协议
        if (!BuiltinPlugin.isGameServer()) {
            springApplication.setWebApplicationType(WebApplicationType.NONE);
        }
        springApplication.run(args);

        LogUtil.openAndCloseServerLog.info("notify process start success!");
        //为了打印服务器停止是否成功，因为不确定停止前服务器启动完没有，要用这个来判断。
        ShutDownPlugin.startup = true;
    }
}
